package org.dawfinn.droiditarian;

import java.io.IOException;
import java.util.Date;

import org.dawfinn.droiditarian.data.DeedsDBAdapter;
import org.dawfinn.droiditarian.deedsource.InternetDeedSource;
import org.dawfinn.droiditarian.view.DeedCursorAdapter;
import org.dawfinn.droiditarian.view.DeedView;
import org.dawfinn.droiditarian.view.UpdateView;
import org.dawfinn.droiditarian.view.UpdateView.State;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class RecentDeeds extends Activity {
	private Cursor deeds;
	private DeedCursorAdapter adapter;
	private final BroadcastReceiver receiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context arg0, Intent arg1) {
			deeds.requery();
		}
	};

	private DeedsDBAdapter dbAdapter;
	private DeedsUpdater updater;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.recent_list);

		dbAdapter = new DeedsDBAdapter(this);
		dbAdapter.open();

		updater = new DeedsUpdater(dbAdapter, new InternetDeedSource(DeedsUpdaterService.UPDATE_PATH));

		deeds = dbAdapter.getDeedsCursor();
		startManagingCursor(deeds);
		adapter = new DeedCursorAdapter(this, deeds);

		final UpdateView updateView = new UpdateView(this);
		updateView.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				doUpdates(updateView);
			}
		});

		ListView deedsList = (ListView) findViewById(R.id.deedList);
		deedsList.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				if (view instanceof UpdateView) {
					doUpdates(updateView);
				} else {
					Intent intent = new Intent(RecentDeeds.this, ExpandedDeed.class);
					intent.putExtra("deedKey", ((DeedView) view).getDeed().getId());
					startActivity(intent);
				}
			}
		});
		deedsList.addFooterView(updateView);
		deedsList.setAdapter(adapter);

		AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);

		Intent startUpdate = new Intent(DeedsUpdaterService.UPDATE_DEEDS_ACTION);
		PendingIntent pendingStartUpdate = PendingIntent.getService(this, 0, startUpdate, 0);
		manager.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis() + AlarmManager.INTERVAL_HALF_DAY, AlarmManager.INTERVAL_HALF_DAY, pendingStartUpdate);
	}

	private void doUpdates(final UpdateView updateView) {
		if (updateView.getState() == State.IDLE) {
			updateView.setState(State.LOADING);
			new DeedsUpdaterAsyncTask(updateView, updater).execute(dbAdapter.getOldestDeedDate());
		}
	}
	
	@Override
	public void onResume() {
		super.onResume();
		IntentFilter filter = new IntentFilter(DeedsUpdaterService.DEEDS_UPDATED);
		registerReceiver(receiver, filter);

		new DeedsUpdaterAsyncTask(new DeedsUpdater(dbAdapter, new InternetDeedSource(DeedsUpdaterService.UPDATE_PATH))).execute();

	}

	@Override
	protected void onPause() {
		super.onPause();
		unregisterReceiver(receiver);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		stopManagingCursor(deeds);
		dbAdapter.close();
	}

	enum DeedsUpdateResult {
		DEEDS_UPDATED(R.string.download_success), NO_DEEDS(R.string.no_deeds), ERROR(R.string.download_error);

		public final int resourceId;

		private DeedsUpdateResult(int resourceId) {
			this.resourceId = resourceId;
		}
	};

	class DeedsUpdaterAsyncTask extends AsyncTask<Date, Boolean, DeedsUpdateResult> {

		private final DeedsUpdater updater;
		private final UpdateView updateView;

		public DeedsUpdaterAsyncTask(DeedsUpdater updater) {
			this(null, updater);
		}

		public DeedsUpdaterAsyncTask(UpdateView updateView, DeedsUpdater updater) {
			this.updateView = updateView;
			this.updater = updater;
		}

		@Override
		protected void onPreExecute() {
			if (updateView != null)
				updateView.setState(State.LOADING);
		}

		@Override
		protected DeedsUpdateResult doInBackground(Date... dates) {
			try {
				if (dates == null || dates.length == 0) {
					return (updater.update() ? DeedsUpdateResult.DEEDS_UPDATED : DeedsUpdateResult.NO_DEEDS);
				} else
					return (updater.update(dates[0]) ? DeedsUpdateResult.DEEDS_UPDATED : DeedsUpdateResult.NO_DEEDS);
			} catch (IOException ex) {
				Log.e("DeedsUpdaterAsyncTask", "IOException while updating deeds", ex);
				return DeedsUpdateResult.ERROR;
			}
		}

		@Override
		protected void onPostExecute(DeedsUpdateResult result) {
			Toast.makeText(RecentDeeds.this, result.resourceId, Toast.LENGTH_SHORT);
			if (updateView != null) {
				if (result == DeedsUpdateResult.NO_DEEDS)
					updateView.setState(State.DISABLED);
				else
					updateView.setState(State.IDLE);
			}
			deeds.requery();
		}
	}
}